package lt.liepasoft.locr.realization;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lt.liepasoft.locr.data.SymbolImage;

public class EncryptedSymbols {
    
    public final int 
            WIDTH=16, HEIGHT=16;
    
    private char[] keys = {
        '3','2','1','0','7','6','5','4','9','8','D','E','F','G','A','B','C','L','M','N','O','H','J','K','U','T','W','V','Q','P','S','R','Y','X','Z','f','g','d','e','b','c','a','n','o','m','k','h','w','v','u','t','s','r','q','p','z','y','x','I','i','l','j'
    };
    
    //TODO: CHANGE TO byte[] array
    private int[][] sequences = {
        //3
        {5,6,8,11,4,12,3,5,4,5,11,5,10,5,9,5,11,6,13,5,12,5,11,5,1,4,6,11,4,6,1,14,3,12,7,6,5,},
        //2
        {6,6,7,12,3,13,2,5,5,5,1,5,5,5,11,5,10,5,10,6,8,6,9,6,8,6,9,6,9,5,10,15,1,31,},
        //1
        {10,6,9,7,5,11,1,35,5,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,},
        //0
        {5,6,7,12,4,12,3,5,4,5,1,5,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,5,1,5,4,5,3,12,4,12,7,6,5,},
        //7
        {0,48,10,5,10,4,11,5,10,5,11,4,11,4,11,5,11,4,11,5,11,5,10,5,11,5,11,5,8,},
        //6
        {6,5,8,11,4,12,3,5,4,5,1,5,11,5,11,13,3,14,2,6,4,5,1,5,5,11,6,10,6,5,1,5,5,5,2,13,4,11,8,5,5,},
        //5
        {4,11,4,12,4,12,4,5,10,5,11,5,1,4,6,12,3,14,3,4,4,6,11,5,11,5,1,4,6,11,4,5,2,13,4,12,7,6,5,},
        //4
        {8,5,11,5,10,6,9,7,8,8,7,9,6,4,1,5,5,4,2,5,4,4,3,5,3,4,4,5,3,48,8,5,11,5,11,5,3,},
        //9
        {5,5,8,11,4,13,2,5,5,5,1,5,6,10,6,11,5,5,1,5,4,6,2,14,3,13,11,5,11,5,1,5,4,5,3,12,4,11,8,5,6,},
        //8
        {5,6,7,12,4,12,3,5,4,5,2,5,4,5,2,5,4,5,3,11,7,8,6,12,3,5,4,5,1,5,6,10,6,11,5,5,1,14,3,12,7,6,5,},
        //D
        {0,11,5,13,3,14,2,4,7,4,1,4,7,4,1,4,8,8,8,8,8,8,8,8,8,8,8,8,7,4,1,4,7,4,1,14,2,14,2,11,5,},
        //E
        {0,52,12,4,12,4,12,15,1,15,1,15,1,4,12,4,12,4,12,4,12,48,},
        //F
        {0,53,11,5,11,5,11,14,2,14,2,14,2,5,11,5,11,5,11,5,11,5,11,5,11,5,11,},
        //G
        {6,5,8,11,4,13,2,4,6,5,1,3,8,3,2,3,12,3,13,3,13,3,6,10,6,7,1,3,9,3,1,3,9,3,1,4,7,4,2,14,3,12,7,5,5,},
        //A
        {5,5,10,7,9,7,9,3,1,4,8,3,1,4,7,4,2,3,7,4,2,3,6,4,3,4,5,4,3,4,4,4,5,4,3,13,3,14,2,3,7,4,1,4,7,4,1,4,8,3,1,3,9,4,},
        //B
        {0,12,4,14,2,15,1,4,7,4,1,4,7,4,1,4,7,4,1,14,2,13,3,14,2,4,7,4,1,4,8,8,8,8,8,19,1,14,2,12,4,},
        //C
        {6,6,7,11,4,13,2,4,7,3,2,3,8,3,1,4,12,4,12,4,12,4,12,4,12,4,8,1,4,3,8,4,1,4,6,4,3,13,4,11,8,5,5,},
        //L
        {0,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,48,},
        //M
        {0,5,6,11,4,12,4,12,4,12,4,9,1,2,4,2,1,6,1,3,2,3,1,6,1,3,2,3,1,6,2,2,2,2,2,6,2,2,2,2,2,6,3,4,3,6,3,4,3,6,3,4,3,6,3,4,3,6,3,4,3,6,4,2,4,3,},
        //N
        {0,5,8,9,7,9,7,10,6,11,5,6,1,4,5,6,2,4,4,6,3,3,4,6,4,3,3,6,4,4,2,6,5,4,1,6,5,4,1,6,6,10,7,9,7,9,8,5,},
        //O
        {5,6,8,10,5,12,3,4,6,4,2,3,8,3,1,4,8,7,10,6,10,6,10,6,10,7,8,4,1,3,8,3,2,4,6,4,3,12,5,10,8,6,5,},
        //H
        {0,4,8,8,8,8,8,8,8,8,8,8,8,56,8,8,8,8,8,8,8,8,8,8,8,8,8,4,},
        //J
        {11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,5,11,10,6,10,6,5,1,14,3,12,6,7,5,},
        //K
        {0,4,7,9,6,5,1,4,5,4,3,4,4,4,4,4,2,5,5,4,1,5,6,10,6,10,6,11,5,6,2,4,4,5,3,4,4,4,5,4,3,4,6,4,2,4,6,4,2,4,7,4,1,4,8,4,},
        //U
        {0,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,1,4,6,5,1,14,3,12,6,8,4,},
        //T
        {0,48,6,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,12,4,6,},
        //W
        {0,2,5,2,5,4,4,3,4,5,4,3,4,2,1,2,4,3,4,2,1,2,4,1,1,2,3,2,2,2,2,2,1,2,3,2,2,2,2,2,2,1,3,2,2,2,2,2,2,1,3,2,2,2,2,1,3,2,2,2,2,2,2,1,3,2,1,2,3,2,1,2,4,1,1,2,3,2,1,2,4,1,1,2,4,3,5,4,4,3,5,4,4,3,6,3,4,3,6,2,3,},
        //V
        {0,3,9,8,8,3,1,4,7,4,2,3,7,4,2,4,6,3,3,4,5,4,4,4,4,3,5,4,3,4,6,3,3,3,7,4,2,3,8,3,2,3,8,3,1,4,8,3,1,3,9,7,10,5,12,4,6,},
        //Q
        {5,5,9,10,4,5,3,5,3,4,6,4,2,3,7,4,1,3,9,3,1,3,9,3,1,3,9,3,1,3,9,3,1,4,8,3,2,3,3,2,2,4,2,4,2,7,4,12,5,12,6,5,2,3,15,1,1,},
        //P
        {0,12,4,14,2,15,1,4,7,9,8,8,8,8,7,9,6,5,1,14,2,13,3,4,12,4,12,4,12,4,12,4,12,4,12,},
        //S
        {5,6,7,12,3,13,3,4,5,5,2,4,6,4,2,5,12,9,8,10,8,10,10,6,1,4,8,8,8,4,1,4,6,5,1,14,3,12,7,6,5,},
        //R
        {0,11,5,13,3,14,2,4,7,4,1,4,7,4,1,4,7,4,1,4,6,4,2,14,2,12,4,10,6,4,4,4,4,4,4,5,3,4,5,5,2,4,6,4,2,4,7,4,1,4,7,5,},
        //Y
        {0,4,8,8,7,4,2,4,6,4,2,5,3,5,4,4,3,4,6,4,2,3,8,8,8,7,10,5,12,3,13,3,13,3,13,3,13,3,13,3,13,3,7,},
        //X
        {1,4,6,4,2,4,6,4,3,4,4,4,5,4,2,4,6,9,9,6,10,6,11,4,11,6,9,8,8,8,7,4,2,4,5,4,3,5,4,4,4,4,3,4,6,4,1,4,8,4,},
        //Z
        {1,15,1,15,1,15,10,5,10,5,10,5,10,4,11,5,9,5,10,5,11,4,10,5,10,5,11,48,},
        //f
        {6,9,4,13,3,13,3,6,7,15,1,15,3,8,9,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,7,},
        //g
        {4,6,2,4,2,9,1,4,1,6,2,7,1,5,4,11,6,10,6,10,6,10,6,5,1,5,4,6,1,15,2,14,5,4,2,5,1,3,7,5,1,5,4,5,3,13,5,8,4,},
        //d
        {11,5,11,5,11,5,11,5,3,7,1,5,2,14,1,6,2,13,4,11,6,10,6,10,6,10,6,5,1,5,4,6,1,15,2,14,5,5,2,4,},
        //e
        {5,6,9,8,6,12,3,6,2,6,2,5,4,5,1,5,6,10,6,42,11,5,12,5,11,6,3,4,4,13,4,11,8,6,4,},
        //b
        {0,5,11,5,11,5,11,5,11,5,1,7,3,14,2,7,2,6,1,6,4,11,6,10,6,10,6,10,6,11,4,5,1,15,1,14,2,4,2,5,5,},
        //c
        {6,5,9,9,5,13,2,6,3,5,2,5,5,10,6,3,2,5,11,5,11,5,11,5,6,3,2,5,6,5,1,5,4,6,1,6,2,6,3,13,5,9,8,6,5,},
        //a
        {5,7,7,10,5,13,2,5,3,6,4,2,5,5,11,5,9,7,5,11,2,8,1,5,1,6,4,5,1,5,5,5,1,5,5,5,1,6,2,7,2,14,3,8,1,4,4,5,3,5,},
        //n
        {0,4,3,6,3,4,1,9,2,15,1,7,3,12,5,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,5,},
        //o
        {5,6,8,10,5,12,3,5,4,5,2,4,6,4,1,5,6,9,8,8,8,8,8,8,8,9,6,5,1,4,6,4,2,6,3,5,3,12,5,10,8,6,5,},
        //m
        {0,2,2,4,3,3,2,2,1,5,2,5,1,20,2,5,1,8,2,4,3,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,6,4,2,4,3,},
        //k
        {0,5,11,5,11,5,11,5,11,5,5,5,1,5,3,6,2,5,2,6,3,5,1,6,4,11,5,11,5,12,4,6,1,6,3,5,4,5,2,5,4,6,1,5,5,5,1,5,6,5,},
        //h
        {0,5,11,5,11,5,11,5,11,5,2,7,2,5,1,9,1,7,3,12,5,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,5,},
        //w
        {0,2,4,3,4,5,4,4,3,6,3,4,3,2,1,3,3,4,3,2,2,2,2,5,3,2,2,2,2,5,2,3,2,2,2,2,1,2,2,3,2,3,1,2,1,2,2,2,3,3,1,2,1,6,4,2,1,2,2,5,4,5,2,5,4,5,2,5,4,4,3,4,5,4,3,4,6,3,4,3,6,3,4,3,3,},
        //v
        {0,5,6,10,6,10,6,5,1,4,6,4,3,4,4,5,3,4,4,4,4,4,4,4,5,4,2,4,6,4,2,4,7,3,2,3,8,8,8,8,9,6,10,6,11,5,11,4,6,},
        //u
        {0,5,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,6,10,5,12,3,7,1,15,2,9,1,4,3,6,3,4,},
        //t
        {8,2,10,6,9,7,9,7,6,32,3,8,8,7,9,7,9,7,9,7,9,7,9,7,9,13,3,13,6,9,1,},
        //s
        {5,7,7,11,4,13,2,5,5,3,3,5,11,7,9,10,7,12,8,10,9,7,11,5,2,3,6,11,4,6,2,13,4,11,7,7,4,},
        //r
        {0,5,3,7,1,31,1,15,1,9,7,8,8,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,7,9,},
        //q
        {4,7,1,4,2,14,1,6,2,7,1,5,4,11,6,10,6,10,6,10,6,5,1,5,4,6,1,15,2,14,5,3,3,5,11,5,11,5,11,5,11,5,},
        //p
        {0,4,2,6,4,14,2,7,2,6,1,6,4,5,1,5,6,10,6,10,6,10,6,11,4,5,1,15,1,14,2,5,3,3,5,5,11,5,11,5,11,5,11,},
        //z
        {1,14,2,14,2,14,11,5,10,5,10,5,10,5,10,5,9,5,10,5,10,5,10,5,10,5,11,48,},
        //y
        {0,4,8,4,1,4,6,4,2,4,6,4,3,4,4,4,4,4,4,4,5,4,2,4,6,4,2,4,6,9,8,8,9,6,10,6,11,4,11,4,11,5,8,7,9,5,10,},
        //x
        {1,5,4,5,2,5,4,5,3,5,2,5,5,4,1,5,7,8,8,8,9,6,10,5,11,6,9,8,8,8,7,10,5,5,2,5,3,5,4,5,1,6,4,11,6,5,},
        //I
        {0,16,1,14,4,10,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,10,4,14,1,16,},
        //i
        {6,5,11,5,11,5,11,5,24,9,7,9,10,5,11,5,11,5,11,5,11,5,11,5,11,5,6,14,1,16,},
        //l
        {6,5,11,5,11,5,7,9,7,9,7,9,7,9,11,5,11,5,11,5,11,5,11,5,11,5,11,5,6,14,1,16,},
        //j
        {6,5,11,5,11,5,23,14,2,14,2,14,13,3,13,3,13,3,13,6,10,7,7,5,1,4,5,5,3,12,5,10,3,},
        
    };
    
    public final Map <Character, SymbolImage> symbols;

    public EncryptedSymbols() {
        symbols = new HashMap<Character, SymbolImage>();

        for (int i=0; i<keys.length; i++){
            symbols.put(keys[i], symbolDecrypt(sequences[i], WIDTH, HEIGHT));
        }
        //let gc do it's job ;)
        keys = null;
        sequences = null;
    }      
    
    
    public static SymbolImage symbolDecrypt(int[] seq, int width, int height){
    	SymbolImage image = new SymbolImage(width, height);
    	
    	//first sequence element is white pixels
        boolean curr = false;
        int px=0;
        
        for (int i=0; i<seq.length; i++){
            for (int j=0; j<seq[i]; j++){
            	image.setPixel(curr, px);
                px++;
            }
            curr=!curr;            
        }
        
        return image;
    }
    
    
    /**
     * TODO: comment
     * @return
     */
    public static int[] symbolEncrypt(SymbolImage image){        
        List <Integer> seq = new ArrayList<Integer>();
        boolean prev = image.getPixel(0);
        //if first pixel isn't black, then add zero to sequence begin
        if (image.getPixel(0)){
            seq.add(0);            
        }
            
        int curr=0;
        
        for (int i=0; i<image.npix; i++){
            if (image.getPixel(i) == prev){
                curr++;
            } else {
                seq.add(curr);
                curr=1;
                prev = image.getPixel(i);
            }
        }
        seq.add(curr);
        int[] seqArray = new int[seq.size()];
        for (int i=0; i<seq.size(); i++)
            seqArray[i] = seq.get(i).intValue();
        
        return seqArray;
    }     
}
